package com.test.liuhb.test.Gson;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.TextView;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.test.liuhb.test.R;
import com.test.liuhb.test.entity.Category;
import com.test.liuhb.test.entity.ModifierSample;
import com.test.liuhb.test.entity.SinceUntilSample;
import com.test.liuhb.test.entity.User;
import com.test.liuhb.test.entity.UserListResult;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by liu.hb on 2018/2/22.
 */
//1.设置布局
@EActivity(R.layout.item_gsonlayout)
public class GsonTest3 extends Activity{
    //2.实例化控件
    @ViewById(R.id.textView)
    TextView tv;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userTest();
        sineUtilTest(4.5);
        GsonTest2();
        GsonTest3();
    }
    //3.初始化控件显示
    @AfterViews
    void initViews() {
        // 初始化控件
        tv.setText("Gson使用指南（三）");
    }
    /**
     *
     * 一、字段过滤的几种方法
     * 基于@Expose注解
     *手动的方式就是使用stream包下的JsonReader类来手动实现反序列化，和Android中使用pull解析XML是比较类似的。
     */
    public void userTest(){
        List<Category> list=new ArrayList<Category>();
        Category category=new Category(1,"平板",null,null);
        Category category2=new Category(2,"笔记本",null,null);
        Category category3=new Category(3,"台式机",null,null);
        list.add(category);
        list.add(category2);
        list.add(category3);
        Category cc=new Category(0,"电脑",list,"电子产品");

        Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .create();
        System.out.println("-------------基于@Expose注解---------------");
        System.out.println(gson.toJson(cc));
    }
    /**
     * 一、字段过滤的几种方法
     * 基于版本
     */
    public void sineUtilTest(double version){
        SinceUntilSample sinceUntilSample = new SinceUntilSample();
        sinceUntilSample.since = "since1";
        sinceUntilSample.until = "until2";
        System.out.println("-------------基于版本---------------");
        Gson gson = new GsonBuilder().setVersion(version).create();
        System.out.println(gson.toJson(sinceUntilSample));
        //当version <4时，结果：{"until":"until"}
        //当version >=4 && version <5时，结果：{"since":"since","until":"until"}
        //当version >=5时，结果：{"since":"since"}
    }
    /**
     * 一、字段过滤的几种方法
     * 基于访问修饰符
     */
    public void GsonTest2(){
        ModifierSample modifierSample = new ModifierSample();
        Gson gson = new GsonBuilder()
        //下面的程序排除了privateField 、 finalField 和staticField 三个字段。
        .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE) .create();
        System.out.println("-------------基于访问修饰符---------------");
        System.out.println(gson.toJson(modifierSample));
        // 结果：{"publicField":"public","protectedField":"protected","defaultField":"default"}
    }
    /**
     * 一、字段过滤的几种方法
     * 基于策略（自定义规则）
     * addSerializationExclusionStrategy 针对序列化
     * addDeserializationExclusionStrategy 针对反序列化
     */
    public void GsonTest3(){
        Gson gson = new GsonBuilder() .addSerializationExclusionStrategy(
                new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    // 这里作判断，决定要不要排除该字段,return true为排除
                   if ("code".equals(f.getName()))
                       return true;
                    //按字段名排除
                    Expose expose = f.getAnnotation(Expose.class);
                    if (expose != null && expose.deserialize() == false)
                        return true;
                    //按注解排除
                    return false;
                }
                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    // 直接排除某个类 ，return true为排除
                    return (clazz == int.class || clazz == Integer.class);
                }
                }) .create();
        UserListResult User = new UserListResult();
        User.code = 11;
        User.message = "message";
        System.out.println("-------------基于策略（自定义规则）---------------");
        System.out.println(gson.toJson(User));

    }

}
